//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//

#pragma once

#include <el.h>


const GUID RILLOG_GUID =
{ 0x85e0b100, 0x4fa, 0x11d1, 0xb7, 0xda, 0x0, 0xa0, 0xc9, 0x3, 0x48, 0xd6 };

//
// Log counters
// (currently none)
//
#define RILLOG_NUMCOUNTERS      0

//
// Zones
//
#define RILLOG_ZONE_CMD         0x00000001
#define RILLOG_ZONE_PRESENCE    0x00000002
#define RILLOG_ZONE_CMD_POLLING 0x00000004
#define RILLOG_ZONE_ERROR       0x80000000

//
// Event IDs
//
#define RILLOG_EVENT_SENDINGCMD             EL_MAKE_EVENTID(    0, EL_SEVERITY_TRACE        )
#define RILLOG_EVENT_PARSERSPOK             EL_MAKE_EVENTID(    1, EL_SEVERITY_TRACE        )
#define RILLOG_EVENT_PARSERSPFAILED         EL_MAKE_EVENTID(    2, EL_SEVERITY_WARNING      )
#define RILLOG_EVENT_RADIOPRESENT           EL_MAKE_EVENTID(    3, EL_SEVERITY_INFORMATIONAL)
#define RILLOG_EVENT_RADIOREMOVED           EL_MAKE_EVENTID(    4, EL_SEVERITY_INFORMATIONAL)
#define RILLOG_EVENT_DRVINITFAILED          EL_MAKE_EVENTID(    5, EL_SEVERITY_ERROR        )
#define RILLOG_EVENT_LOWMEMORY              EL_MAKE_EVENTID(    6, EL_SEVERITY_CRITICAL     )
#define RILLOG_EVENT_TOOMANYTIMEOUTS        EL_MAKE_EVENTID(    7, EL_SEVERITY_CRITICAL     )
#define RILLOG_EVENT_COULDNTSENDINIT        EL_MAKE_EVENTID(    8, EL_SEVERITY_CRITICAL     )
#define RILLOG_EVENT_GENERALREINIT          EL_MAKE_EVENTID(    9, EL_SEVERITY_CRITICAL     )
#define RILLOG_EVENT_SMSREINIT              EL_MAKE_EVENTID(   10, EL_SEVERITY_CRITICAL     )
#define RILLOG_EVENT_COMMANDTHREADEXIT      EL_MAKE_EVENTID(   11, EL_SEVERITY_INFORMATIONAL)
#define RILLOG_EVENT_PARSEDGARBAGE          EL_MAKE_EVENTID(   12, EL_SEVERITY_TRACE        )
#define RILLOG_EVENT_PARSEDNOTIFICATION     EL_MAKE_EVENTID(   13, EL_SEVERITY_TRACE        )
#define RILLOG_EVENT_USSDRECEIVED           EL_MAKE_EVENTID(   14, EL_SEVERITY_TRACE        )
#define RILLOG_EVENT_CMDTIMEDOUT            EL_MAKE_EVENTID(   15, EL_SEVERITY_WARNING      )
#define RILLOG_EVENT_CMDTIMEDOUTSUPPRESSED  EL_MAKE_EVENTID(   16, EL_SEVERITY_WARNING      )
#define RILLOG_EVENT_NOONEWAITING           EL_MAKE_EVENTID(   17, EL_SEVERITY_INFORMATIONAL)
#define RILLOG_EVENT_UNRECOGNIZEDRSP        EL_MAKE_EVENTID(   18, EL_SEVERITY_INFORMATIONAL)
#define RILLOG_EVENT_CMDRSPOK               EL_MAKE_EVENTID(   19, EL_SEVERITY_TRACE        )
#define RILLOG_EVENT_CMDRSPERROR            EL_MAKE_EVENTID(   20, EL_SEVERITY_TRACE        )
#define RILLOG_EVENT_SENDINGCMDSUPPRESSED   EL_MAKE_EVENTID(   21, EL_SEVERITY_TRACE        )
#define RILLOG_EVENT_PRSRSPOKSUPPRESSED     EL_MAKE_EVENTID(   22, EL_SEVERITY_TRACE        )
#define RILLOG_EVENT_PRSRSPFAILEDSUPPRESSED EL_MAKE_EVENTID(   23, EL_SEVERITY_WARNING      )
#define RILLOG_EVENT_GPRSFATALERROR         EL_MAKE_EVENTID(   24, EL_SEVERITY_ERROR        )
#define RILLOG_EVENT_RADIOFAILUREREASON     EL_MAKE_EVENTID(   25, EL_SEVERITY_TRACE        )

class CRilEventLog
{
private:
    HANDLE          m_hLog;
    const GUID *    m_pGuid;
    DWORD           m_dwNumCounters;

public:
    CRilEventLog()
    {
        m_hLog = NULL;
        m_pGuid = &RILLOG_GUID;
        m_dwNumCounters = RILLOG_NUMCOUNTERS;
    }

    ~CRilEventLog()
    {
        (void)Unregister();
    }

    HANDLE GetHandle()
    {
        ASSERT(NULL != m_hLog);
        return m_hLog;
    }

    HRESULT Register()
    {
        if (NULL != m_hLog)
            return E_FAIL;

        HANDLE hLog = NULL;
        HRESULT hr = EL_Register(m_pGuid, m_dwNumCounters, &hLog);
        if (SUCCEEDED(hr))
        {
            ASSERT(NULL != hLog);
            m_hLog = hLog;

            // Turn off polling commands (e.g. +CSQ) by default
            EL_SetZones(m_hLog, ~RILLOG_ZONE_CMD_POLLING);
        }

        return hr;
    }

    HRESULT Unregister()
    {
        if (NULL == m_hLog)
            return E_FAIL;

        HRESULT hr = EL_Unregister(GetHandle());
        m_hLog = NULL;
        return hr;
    }

    HRESULT IncrementCounter(DWORD dwIndex)
    {
        if (NULL == m_hLog)
            return E_FAIL;
        
        ASSERT(dwIndex < m_dwNumCounters);
        HRESULT hr = EL_IncrementCounter(GetHandle(), dwIndex);
        ASSERT(SUCCEEDED(hr));
        return hr;
    }

    HRESULT ResetCounter(DWORD dwIndex)
    {
        if (NULL == m_hLog)
            return E_FAIL;
        
        ASSERT(dwIndex < m_dwNumCounters);
        HRESULT hr = EL_ResetCounter(GetHandle(), dwIndex);
        ASSERT(SUCCEEDED(hr));
        return hr;
    }

    HRESULT LogEvent(DWORD dwZones, DWORD dwEventId)
    {
        if (NULL == m_hLog)
            return E_FAIL;
        
        return EL_LogEvent(GetHandle(), dwZones, dwEventId, 0x0);
    }

    HRESULT LogEvent(DWORD dwZones, DWORD dwEventId, const CHAR * sz, DWORD * pdw)
    {
        if (NULL == m_hLog)
            return E_FAIL;
        
        return EL_LogEvent(GetHandle(), dwZones, dwEventId, 0x13, sz, pdw);
    }

    HRESULT LogEvent(DWORD dwZones, DWORD dwEventId, const CHAR * sz)
    {
        if (NULL == m_hLog)
            return E_FAIL;
        
        return EL_LogEvent(GetHandle(), dwZones, dwEventId, 0x3, sz);
    }

    HRESULT LogEvent(DWORD dwZones, DWORD dwEventId, const DWORD dw)
    {
        if (NULL == m_hLog)
            return E_FAIL;
        
        return EL_LogEvent(GetHandle(), dwZones, dwEventId, 0x1, &dw);
    }

};

extern CRilEventLog g_RilLog;

